Skip to content

[deckhouse-cli] Add registry error diagnostics for d8 mirror#320

Merged
ldmonster merged 12 commits intomainfrom
feat/registry-error-diagnostics
Apr 13, 2026
Merged

[deckhouse-cli] Add registry error diagnostics for d8 mirror#320
ldmonster merged 12 commits intomainfrom
feat/registry-error-diagnostics

Conversation

@Glitchy-Sheep
Copy link
Copy Markdown
Contributor

@Glitchy-Sheep Glitchy-Sheep commented Apr 6, 2026

Summary

User-friendly diagnostics for registry errors in d8 mirror pull/push. At the application/UI layer, known errors (TLS, DNS, auth, timeout, etc.) are diagnosed and shown with possible causes and actionable solutions.

Demo

diag

What it does

  • Diagnoses 10 registry error categories: EOF, TLS/certificate, auth (401/403), rate limiting (429), server errors (5xx), DNS, timeout, network, image/repo not found
  • Colored terminal output with cause/solution pairs (TTY-aware, respects NO_COLOR)
  • Detects errors via errors.Is/errors.As through the full error chain, with string fallback for HEAD responses

How HelpfulError flows

  1. Command's RunE calls business logic, gets a regular error
  2. Command passes it to its own errdetect.Diagnose(err) - if recognized, returns *HelpfulError; otherwise the original error is returned as-is
  3. Error bubbles up through cobra to root.go
  4. root.go checks errors.As(err, &helpErr) - if it's a HelpfulError, prints colored diagnostic with causes/solutions; otherwise prints the plain error

Key: root.go knows nothing about specific errdetect packages. Any command can return a HelpfulError - it will be caught and formatted.

Architecture

  • pkg/diagnostic/ - generic HelpfulError type with Format() for colored output
  • internal/mirror/errmatch/ - error matchers for flow control (IsImageNotFound, IsRepoNotFound)
  • internal/mirror/cmd/pull/errdetect/ - pull-specific error diagnostics (advises --license, --source-login)
  • internal/mirror/cmd/push/errdetect/ - push-specific error diagnostics (advises --registry-login, --registry-password)
  • root.go catches any *HelpfulError via errors.As - does not import any errdetect
  • Each command owns its diagnostics - prevents false advice across commands

- Classify 11 types of registry errors (EOF, TLS, auth, DNS, timeout,
  network, rate limit, server errors, image/repo not found, OCI artifacts)
  and show user-friendly diagnostics with possible causes and solutions
- Detect errors via errors.Is/errors.As through go-containerregistry's
  error chain including multierrs from HTTPS/HTTP fallback
- Output colored diagnostics to stderr only when TTY is detected,
  respecting NO_COLOR and FORCE_COLOR environment variables
- Integration tests verify classification against real HTTP responses
  from httptest servers (no Docker required)

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
@Glitchy-Sheep Glitchy-Sheep self-assigned this Apr 6, 2026
- Split monolithic registryerr into three packages: pkg/diagnostic (generic HelpfulError),
  pkg/registry/errdiag (registry classifier), pkg/registry/errmatch (flow-control matchers)
- Each command classifies errors with its own domain classifier; root.go only catches
  HelpfulError via errors.As, preventing false diagnostics across unrelated commands
- Extend OCI media type detection to cover all Deckhouse artifact types, not just Trivy
- Unify Trivy error handling: errors propagate to Classify instead of being intercepted
  and replaced with a warning string in the pusher retry loop
- Add typed transport.Error checks in errmatch with string fallback for HEAD responses
- Guard against double classification in Classify via errors.As check

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
- Package is only used by mirror pull/push, no need to keep it in pkg

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
@Glitchy-Sheep Glitchy-Sheep added the enhancement New feature or request label Apr 10, 2026
- Classifier contains application-level advice (CLI flags, docs links) specific to mirror commands
- Document classifier placement convention in README and doc.go

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
@Glitchy-Sheep Glitchy-Sheep marked this pull request as ready for review April 10, 2026 12:29
Glitchy-Sheep and others added 7 commits April 10, 2026 19:16
- Pull and push each have their own errdetect package with command-specific advice
- Pull auth suggests --license and --source-login, push suggests --registry-login
- Push references <registry> positional argument, pull references --source flag

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
- Error matchers are only used by mirror commands, belong in internal
- File names match function names: classify.go -> diagnose.go (better name for clarity in general)

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
- Display each wrapped error level on its own line with increasing indentation for easier root-cause identification
- Walk errors.Unwrap() to extract per-level context instead of showing a single flattened message
- Update doc examples in README.md and doc.go to reflect the chain format

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
- Each cause now carries its own solutions so the user sees actionable advice next to the relevant problem, not two disconnected lists
- Add Suggestion type pairing Cause with Solutions in HelpfulError
- Causes without solutions (e.g. "registry closed connection") render cleanly without empty arrows
- Regroup all pull and push classifier suggestions into cause-solution pairs

Signed-off-by: Roman Berezkin <roman.berezkin@flant.com>
Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
Signed-off-by: Pavel Okhlopkov <pavel.okhlopkov@flant.com>
@ldmonster ldmonster merged commit 4ec302d into main Apr 13, 2026
5 checks passed
@ldmonster ldmonster deleted the feat/registry-error-diagnostics branch April 13, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants